function ListArea(p_ctx, p_left, p_top)
{
/*====================================== PROPERTIES =========================================*/
	//list data; array
	this.getList = function() { if (!this.list) this.list = new Array(); return this.list; }
	this.setList = function(p_list) { this.list = p_list; }
	this.setList(new Array());

	// Item management
	this.addItem = function(p_item) { if (p_item) this.list.push(p_item); }
	this.removeItem = function(p_index) { this.list.pArrRemoveAt(p_index); }
	
	this.getSelectionStartIndex = function() { return this.selection_start_index; }
	this.setSelectionStartIndex = function(p_index) { this.selection_start_index=p_index; }
	this.setSelectionStartIndex(null);

	this.getSelectionEndIndex = function() { return this.selection_end_index; }
	this.setSelectionEndIndex = function(p_index) { this.selection_end_index=p_index; }
	this.setSelectionEndIndex(null);
	
	this.prev_start=this.selection_start_index;
	this.prev_end = this.selection_end_index;

	// If multiple selection is not allowed, start index and end index above will always be the same
	// In any case, if they are the same, they can be considered equivalent to a selected index 
	this.getMultipleSelectionAllowed = function() { return this.multiple_selection_allowed; }
	this.setMultipleSelectionAllowed = function (p_allowed) { this.multiple_selection_allowed=p_allowed;}
	this.setMultipleSelectionAllowed(false);

	this.setBackColor = function(p_color) { this.back_color = p_color; }
	this.getBackColor = function() { return this.back_color; }
	this.setBackColor("white");

	this.setForeColor = function(p_color) { this.fore_color = p_color; }
	this.getForeColor = function() { return this.fore_color; }
	this.setForeColor("black");

	this.setSelectionColor = function(p_color) { this.selection_color = p_color; }
	this.getSelectionColor=function() { return this.selection_color; }
	this.setSelectionColor("silver");

	this.getHasFocus = function() { return this.hasFocus ? this.hasFocus : false; }
	this.setHasFocus = function(p_focus) { this.hasFocus=p_focus; }
	this.setHasFocus(false);
		
	this.getTop = function() { return this.top; }
	this.setTop = function(p_top) { if (p_top >=0) { this.top = p_top; } }
	this.setTop(p_top?p_top : 0);

	this.getLeft = function() { return this.left; }
	this.setLeft = function(p_left) { if (p_left >=0) { this.left = p_left; } }
	this.setLeft(p_left?p_left : 0);
		
	this.getWidth = function() { return this.width; }
	this.setWidth = function(p_width) { if (p_width >= 0) this.width = p_width; }
	this.setWidth(70);
	
	this.getItemHeight = function() { return this.item_height; }
	this.setItemHeight = function(p_height) { if (p_height >= 0) this.item_height = p_height; }
	this.setItemHeight(25);
	
	// Overall height; number; read only
	this.getHeight = function() { return this.list.length * this.item_height; } 
	
	// Drawing context
	this.setContext = function(p_ctx) { this.ctx = p_ctx; }
	this.getContext = function() { return this.ctx; }
	this.setContext(p_ctx? p_ctx : null);

	this.dragging_to_select = false;
	
/*====================================== EVENTS ============================================*/
	this.onSelectionChanged = null;
	
/*====================================== METHODS ===========================================*/

/*==========================================================================================*/

	this.getMouseListItem = function(p_y) // determines the list item over which mouse cursor is positioned. We assume x coordinates is redundant
	{
		for (var i=0; i<this.list.length; i++) 
				if ((p_y >= (this.item_height * i)) && (p_y <= (this.item_height * (i+1))))
					return i;
	}
	this.mouseMove = function(p_x, p_y)
	{
		if (this.dragging_to_select) this.selection_end_index = this.getMouseListItem(p_y);
		if (this.onMouseMove) this.onMouseMove(p_x, p_y);
	}
	this.mouseDown = function(p_x, p_y)
	{
		this.selection_start_index = this.getMouseListItem(p_y);
		this.selection_end_index = this.selection_start_index;
		this.dragging_to_select = true;
		if (this.onMouseDown) this.onMouseDown(p_x, p_y);		
	}
	this.mouseUp = function(p_x, p_y)
	{
		this.selection_end_index = this.getMouseListItem(p_y);
		this.dragging_to_select = false;
		if (this.onMouseUp) this.onMouseUp(p_x, p_y);
		if (this.onSelectionChanged && (!(this.prev_start == this.selection_start_index && this.prev_end == this.selection_end_index)))
		{
			this.prev_start=this.selection_start_index;
			this.prev_end = this.selection_end_index;
			this.onSelectionChanged (this.selection_start_index, this.selection_end_index);
		}		
	}
	
	this.mouseOut = function() { if (this.onMouseOut) this.onMouseOut(); }
	this.mouseOver = function() { if (this.onMouseOver) this.onMouseOver(); }
	this.keyPress = function(key) { if (this.onKeyPress) this.onKeyPress(key); }
	this.keyDown = function(key) { if (this.onKeyDown) return this.onKeyDown(key); }

	this.render = function()
	{	
		if (!this.ctx) return;
		this.ctx.strokeStyle=this.fore_color;
		this.ctx.strokeRect(this.left, this.top, this.width, this.getHeight());
		for (var i=0; i<this.list.length; i++)
		{
			this.ctx.fillStyle=this.back_color;	
			if (hasValue(this.selection_start_index) && hasValue(this.selection_end_index))
			{
				var max = Math.max(this.selection_start_index,this.selection_end_index);
				var min = Math.min(this.selection_start_index,this.selection_end_index);
				if (i >= min && i <= max) this.ctx.fillStyle=this.selection_color;	
			}		
							
			this.ctx.fillRect(this.left, this.top+(this.item_height * (i)), this.width, this.item_height);
			this.ctx.fillStyle=this.fore_color;
			this.ctx.fillText(this.list[i], this.left+10, this.top+(this.item_height * (i)));			
		}		
	}
	this.render();
}